package com.heima.comment.service.impl;

import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentRepay;
import com.heima.comment.pojos.ApCommentRepayLike;
import com.heima.comment.pojos.CommentRepayVo;
import com.heima.comment.service.CommentRepayService;
import com.heima.feign.user.IUserClient;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author luoTao
 * @project xmsz
 * @date 2024/1/27 10:42:51
 */
@Service
@Slf4j
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private IUserClient userClient;

    /**
     * @param dto :
     * @return ResponseResult<?>
     * @author 18297
     * @date 2024/1/27 10:44
     * @description 保存回复评论
     */
    @Override
    public ResponseResult<?> saveCommentRepay(CommentRepaySaveDto dto) {
        //1.检查参数
        if (dto == null || StringUtils.isBlank(dto.getContent()) || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.是否超过140个字符
        if (dto.getContent().length() > 140) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论内容不能超过140字");
        }

        // 3.判断是否登录
        ApUser user = AppThreadLocalUtil.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        //4.保存评论
        // 远程调用通过useId查到用户对象
        ApUser dbUser = userClient.findUserById(user.getId());//
        if (dbUser == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "当前登录信息有误");
        }
        // 新建评论对象保存用户信息和评论
        ApCommentRepay apCommentRepay = new ApCommentRepay();
        apCommentRepay.setAuthorId(dbUser.getId()); //
        apCommentRepay.setContent(dto.getContent());
        apCommentRepay.setCreatedTime(new Date());
        apCommentRepay.setCommentId(dto.getCommentId());
        apCommentRepay.setAuthorName(dbUser.getName());
        apCommentRepay.setUpdatedTime(new Date());
        apCommentRepay.setLikes(0);
        mongoTemplate.save(apCommentRepay);

        //5更新回复数量+1
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        apComment.setReply(apComment.getReply() + 1);
        mongoTemplate.save(apComment);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * @param dto :
     * @return ResponseResult<?>
     * @author 18297
     * @date 2024/1/27 11:10
     * @description 查看评论回复列表
     */
    @Override
    public ResponseResult<?> loadCommentRepay(CommentRepayDto dto) {
        //1.检查参数
        if (dto == null || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        int size = 20;
        if (Objects.nonNull(dto.getSize())){
            size = dto.getSize();
        }

        //2.加载数据，构造条件根据评论的id去查询createdTime小于minDate的数据
        Query query = Query.query(Criteria.where("commentId")
                .is(dto.getCommentId()).and("createdTime").lt(dto.getMinDate()));
        // 按照createdTime倒序排序展示size条数据
        query.with(Sort.by(Sort.Direction.DESC, "createdTime")).limit(size);
        // 调用方法进行查询，得到所有回复评论的回复集合
        List<ApCommentRepay> list = mongoTemplate.find(query, ApCommentRepay.class);
        //3.数据封装返回
        //判断用户是否登录
        ApUser user = AppThreadLocalUtil.getUser();
        if (user == null) {
            return ResponseResult.okResult(list);
        }
        //3.2 用户已登录
        //需要查询当前评论中哪些数据被点赞了，将回复集合中的id提取出来成为一个idList集合
        List<String> idList = list.stream().map(x -> x.getId()).collect(Collectors.toList());
        //构造条件，根据回复评论的评论的id和文章作者id去查询
        Query query1 = Query.query(Criteria.where("commentRepayId").in(idList).and("authorId").is(user.getId()));
        // 如果集合为空，说明所有评论没有人点赞，直接返回回复评论的评论list数据
        List<ApCommentRepayLike> apCommentRepayLikes = mongoTemplate.find(query1, ApCommentRepayLike.class);
        if (apCommentRepayLikes.isEmpty()) {
            return ResponseResult.okResult(list);
        }
        // 准备集合，装返回的数据
        List<CommentRepayVo> resultList = new ArrayList<>();
        //不为空，遍历集合集合获取点赞数据
        list.forEach(x -> {
            CommentRepayVo vo = new CommentRepayVo();
            BeanUtils.copyProperties(x, vo);
            for (ApCommentRepayLike apCommentRepayLike : apCommentRepayLikes) {
                if (x.getId().equals(apCommentRepayLike.getCommentRepayId())) {
                    vo.setOperation((short) 0);
                    break;
                }
            }
            resultList.add(vo);
        });
        return ResponseResult.okResult(resultList);
    }

    /**
     * @param dto :
     * @return ResponseResult<?>
     * @author 18297
     * @date 2024/1/27 13:13
     * @description 给回复的评论点赞
     */
    @Override
    public ResponseResult<?> saveCommentRepayLike(CommentRepayLikeDto dto) {
        //1.检查参数
        if (dto == null || dto.getCommentRepayId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2.判断是否登录
        ApUser user = AppThreadLocalUtil.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        ApCommentRepay apCommentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);

        //3.点赞
        if (apCommentRepay != null && dto.getOperation() == 0) {
            //更新评论点赞数量
            apCommentRepay.setLikes(apCommentRepay.getLikes() + 1);
            mongoTemplate.save(apCommentRepay);

            //保存评论点赞数据
            ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
            apCommentRepayLike.setCommentRepayId(apCommentRepay.getId());
            apCommentRepayLike.setAuthorId(user.getId());
            mongoTemplate.save(apCommentRepayLike);
        } else {
            //更新评论点赞数量
            int tmp = apCommentRepay.getLikes() - 1;
            tmp = tmp < 1 ? 0 : tmp;
            apCommentRepay.setLikes(tmp);
            mongoTemplate.save(apCommentRepay);

            //删除评论点赞
            Query query = Query.query(Criteria.where("commentRepayId").is(apCommentRepay.getId()).and("authorId").is(user.getId()));
            mongoTemplate.remove(query, ApCommentRepayLike.class);
        }

        //4.取消点赞
        Map<String, Object> result = new HashMap<>();
        result.put("likes", apCommentRepay.getLikes());
        return ResponseResult.okResult(result);
    }
}